
#ifndef COMPONENT_H
#define COMPONENT_H

#include <pcl/io/pcd_io.h>
#include <pcl/common/transforms.h>
#include <pcl/sample_consensus/ransac.h>
#include <pcl/sample_consensus/sac_model_plane.h>
#include <pcl/features/normal_3d_omp.h>
#include <pcl/common/transforms.h>
#include <pcl/common/centroid.h>
#include <algorithm>

using namespace std;
using namespace pcl;

/**
 * @brief Class representing a component inside the circuit
 * @author Alberto Basso, Luca Tumelero
 * @file component.h
 */
class Component
{
public:
/**
 * @brief Empty costructor
 *
 */
    Component();
/**
 * @brief Full costructor
 *
 * @param[in] cloud_ Input cloud
 * @param[in] componentIndices_ Indices of the components inside the input cloud
 * @param[in] generatingIndex_ Index clicked from the interface inside the component
 * @param[in] clusterThreshold_ Threshold for the cluster extraction
 * @param[in] colorThreshold_ Color Threshold for color cluster filtering
 */
    Component(PointCloud<PointXYZRGB>::Ptr cloud_, PointIndices::Ptr componentIndices_, int generatingIndex_, double clusterThreshold_, int colorThreshold_);
    /**
     * @brief Two parameters costructor
     * @param[in] cloud_ Input cloud
     * @param[in] componentIndices_ Indices of the components inside the input cloud
     */
    Component(PointCloud<PointXYZRGB>::Ptr cloud_, PointIndices::Ptr componentIndices_);
    /**
     * @brief Return input cloud
     * @return PointCloud<PointXYZRGB> Return input cloud
     */
    PointCloud<PointXYZRGB>::Ptr getCloud();
    /**
     * @brief Return indices of the component inside the cloud
     * @return PointIndices::Ptr Return PointIndices component
     */
    PointIndices::Ptr getIndices();
    /**
     * @brief Return the cloud representing the component
     * @return PointCloud<PointXYZRGB> Return component cloud
     */
    PointCloud<PointXYZRGB>::Ptr getComponentCloud();
    /**
     * @brief Returns the index of the point clicked on the cloud to segment this component
     * @return int Index of the point clicked
     */
    int getGeneratingIndex();
    /**
     * @brief Returns the color threshold used to segment the component.
     * @return int Clustering color threshold of segmentation.
     */
    int getColorThreshold();
    /**
     * @brief Returns the clustering threshold used to segment the component.
     * @return double Clustering threshold of segmentation.
     */
    double getClusterThreshold(); //
    /**
     * @brief Returns red value of the RGB color of the generating point.
     *
     * @return int Return red value.
     */
    int getColR();
    /**
     * @brief Returns green value of the RGB color of the generating point.
     * @return int Return green value.
     */
    int getColG();
    /**
     * @brief Returns blue value of the RGB color of the generating point.
     * @return int Return blue value.
     */
    int getColB();
    /**
     * @brief Returns X coordinate of the point.
     * @return float Return X coordinate.
     */
    float getPosX();
    /**
     * @brief Returns Y coordinate of the point.
     * @return float Return Y coordinate.
     */
    float getPosY();
    /**
     * @brief Returns Z coordinate of the point.
     * @return float Return Z coordinate.
     */
    float getPosZ();
    /**
     * @brief Returns the number of indices representing the component.
     * @return int Size of component's pointIndices vector.
     */
    int getSize();
    /**
     * @brief Returns the average color of the points of the cloud in RGB.
     * @return Eigen::Vector3f RGB average color.
     */
    Eigen::Vector3f getAverageColor();
    /**
     * @brief Returns the approximation of the centroid of the component.
     * @return PointXYZRGB Component's center.
     */
    PointXYZRGB getCenterOfMass();
    /**
     * @brief Returns a 4f vector representing the plane normal and it's distance from origin.
     * @return Eigen::VectorXf Plane coefficients
     */
    Eigen::VectorXf getPlaneCoefficients ();
    /**
     * @brief Returns the value of the estimated radius of the component from its center.
     * @return float Radius of the component
     */
    float getRadiusToCenterOfMass();

private:
    PointCloud<PointXYZRGB>::Ptr cloud;
    PointIndices::Ptr componentIndices;
    int generatingIndex;
    double clusterThreshold;
    int colorThreshold;
};
#endif // COMPONENT_H
